/*
			Author: Ozcan Degirmenci (Boot)
			E-Mail: odegirmenci@hotmail.com
			Date:	4 Jan 2005
*/

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;


namespace Ling.ZhControls
{
	/// <summary>
	///  Contains static painting methods
	/// </summary>
	internal class StaticPaint
	{
		internal const int WM_MOUSEMOVE              = 0x0200;
		internal const int WM_LBUTTONDOWN            = 0x0201;
		internal const int WM_LBUTTONUP              = 0x0202;
		internal const int WM_LBUTTONDBLCLK          = 0x0203;
		internal const int WM_RBUTTONDOWN            = 0x0204;
		internal const int WM_RBUTTONUP              = 0x0205;
		internal const int WM_RBUTTONDBLCLK          = 0x0206;
		internal const int WM_MBUTTONDOWN            = 0x0207;
		internal const int WM_MBUTTONUP              = 0x0208;
		internal const int WM_MBUTTONDBLCLK          = 0x0209;

		[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true, ExactSpelling=true)]
		public static extern int SetLayeredWindowAttributes(HandleRef hwnd, 
			int crKey, byte bAlpha, int dwFlags);

		[DllImport ("user32.dll")]
		public static extern int ShowWindow (IntPtr hWnd, int nCmd);


		[DllImport("comctl32.dll")]
		public extern static int DllGetVersion(ref DLLVERSIONINFO dvi);

		[DllImport("comctl32.dll", CharSet=CharSet.Auto)]
		public static extern bool ImageList_DrawIndirect(ref IMAGELISTDRAWPARAMS pimldp);

		[DllImport("comctl32.dll")]
		public static extern bool InitCommonControlsEx(INITCOMMONCONTROLSEX icc);

		public enum ImageListDrawStyles
		{
			ILD_TRANSPARENT = 0x1,
			ILS_SATURATE	= 0x4
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct DLLVERSIONINFO
		{
			public int cbSize;
			public int dwMajorVersion;
			public int dwMinorVersion;
			public int dwBuildNumber;
			public int dwPlatformID;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct IMAGELISTDRAWPARAMS 
		{
			public int cbSize;
			public IntPtr himl;
			public int i;
			public IntPtr hdcDst;
			public int x;
			public int y;
			public int cx;
			public int cy;
			public int xBitmap;
			public int yBitmap;
			public int rgbBk;
			public int rgbFg;
			public int fStyle;
			public int dwRop;
			public int fState;
			public int Frame;
			public int crEffect;
		
			public ImageListDrawStyles FStyle
			{
				set {fStyle = Convert.ToInt32(value);}
			}

			public ImageListDrawStyles FState
			{
				set {fState = Convert.ToInt32(value);}
			}
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public class INITCOMMONCONTROLSEX 
		{
			public int Size = 8;
			public int Flags=0;
		}

		/// <summary>
		///  Draws a image.
		///  If disabled flag is not true drawing is normal.
		///  But if disabled if false than we use two different method according to the clients 
		///  widnows version
		/// </summary>
		/// <param name="g"></param>
		/// <param name="image"></param>
		/// <param name="rct"></param>
		/// <param name="disabled"></param>
		public static void DrawImage(Graphics g, Image image, Rectangle rct, bool disabled)
		{
			if(image == null)
				return;

			if (!disabled)
			{
				g.DrawImage(image, rct);
			}
			else
			{
				// we use ILS_SATURATE for XP drawing
				DLLVERSIONINFO dvi = new DLLVERSIONINFO();
				dvi.cbSize = Marshal.SizeOf(typeof(DLLVERSIONINFO));
				DllGetVersion(ref dvi);
				if (dvi.dwMajorVersion < 6)
				{
					ImageAttributes attributes = new ImageAttributes ();
					float[][] matrix = new float[5][];
					matrix[0] = new float[] { 0.2222f, 0.2222f, 0.2222f, 0.0000f, 0.0000f };
					matrix[1] = new float[] { 0.2222f, 0.2222f, 0.2222f, 0.0000f, 0.0000f };
					matrix[2] = new float[] { 0.2222f, 0.2222f, 0.2222f, 0.0000f, 0.0000f };
					matrix[3] = new float[] { 0.3333f, 0.3333f, 0.3333f, 0.7500f, 0.0000f };
					matrix[4] = new float[] { 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f };
					attributes.SetColorMatrix(new ColorMatrix(matrix));
					g.DrawImage(image, rct, 0, 0, image.Size.Width, 
						image.Size.Height, GraphicsUnit.Pixel, attributes);
				}
				else
				{
					ImageList imageList = new ImageList();
					imageList.ImageSize = image.Size;
					imageList.ColorDepth = ColorDepth.Depth32Bit;		
					imageList.Images.Add(image);
	
					IntPtr hdc = g.GetHdc();
					IMAGELISTDRAWPARAMS ildp = new IMAGELISTDRAWPARAMS();
					ildp.cbSize = Marshal.SizeOf(typeof(IMAGELISTDRAWPARAMS));
					ildp.himl = imageList.Handle;
					ildp.i = 0; // image index
					ildp.hdcDst = hdc;
					ildp.x = rct.X;
					ildp.y = rct.Y;
					ildp.cx = 0;
					ildp.cy = 0;
					ildp.xBitmap = 0;
					ildp.yBitmap = 0;
					ildp.FState = ImageListDrawStyles.ILS_SATURATE;
					ildp.FStyle = ImageListDrawStyles.ILD_TRANSPARENT;
					ildp.Frame = -100;
					ImageList_DrawIndirect(ref ildp);
					g.ReleaseHdc(hdc);
				}
			}
		}

        public static string ToErrorString(Exception ex)
        {
            if (ex == null)
                return "";

			string returnMsg = string.Empty;

			while (ex != null)
            {
				returnMsg = ex.Message ;
				if (ex.StackTrace != null)
					returnMsg += " in " + ex.StackTrace;
				ex = ex.InnerException;
				returnMsg += " with the inner exception ";
			}

			if (returnMsg != string.Empty)
				returnMsg = returnMsg.Substring(0, returnMsg.Length  - 26);
			return returnMsg;
		}
    }
}
